﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;

namespace YanZhiwei.DotNet2.Utilities.AspNet
{
    /// <summary>
    /// HttpWebRequest 帮助类
    /// </summary>
    public class HttpWebRequestHelper
    {
        /*
         * 参考：
         * 1: “Request Header“: 
            第一行： Get / Http/1.1  这里面有三个信息：①"Get",表示请求的模式。 ②“/"，请求网站的根目录。  ③"http/1.1"，这个就是http的版本。
            第二行： Host 请求目标的网站，跟“/"并一起就是"www.baidu.com/"。
            第三行： Connection 默认为“keep-Alive“，这里就是文章开头所说的默认支持长连接。
            第四行： Cache-Control 这玩意跟缓存有关，其中max-age表示缓存的时间(s)。
            第五行：User-Agent 告诉serve我client的身份，一般由浏览器决定，比如：浏览器类型，版本等等。
            第六行：Accept 以及后面的Accept打头的都是表明client能够接收的种类和类型。
            最后一行：Cookie 如果我们第一次向baidu请求时是没有cookie信息这一栏的，因为在浏览器下找不到于baidu相关的cookie，当我们第二次刷新页面时，get请求就会找到本地的cookie并附带给server。
           2: "Response Header":
            第一行： Http/1.1 200 OK 这个估计大家都知道吧，200表示返回的状态码，OK则是描述性的状态码。
            第二行：Date 表示服务器响应的时间。
            第三行: Server 响应客户端的服务器。
            第四行：Content-Length 表示服务器返回给客户端正文的字节流长度。
            第五行：Content-Type 表示正文的类型。
            第七行：Expires 告诉client绝对的过期时间，比如2012.1.10,在这个时间内client都可以不用发送请求而直接从client的cache中获取，对js，css，image的缓存很有好处，所以说用好了这个属性对我们http的性能有很大的帮助。
            第八行：Content-Encoding 文档类型的编码方式，服务器端采用gzip的形式进行了文档压缩，此时减小了文档，利于下载，但是必须client端支持 gzip的解码操作。
         */
        #region 发起HttpWebResponse请求
        /// <summary>
        /// 发起HttpWebResponse请求
        /// </summary>
        /// <param name="url">请求连接</param>
        /// <param name="credentials">请求参数</param>
        /// <param name="httpWebRequestRule">请求设置『委托』，当委托等于NULL的时候，默认请求；否则使用所设置的HttpWebRequest</param>
        /// <returns>HttpWebResponse</returns>
        public static HttpWebResponse CreateHttpWebRequest(string url, byte[] credentials, Func<string, HttpWebRequest> httpWebRequestRule)
        {

            HttpWebRequest _request = null;
            if (httpWebRequestRule != null)
            {
                _request = httpWebRequestRule(url);
            }
            else
            {
                _request = WebRequest.Create(url) as HttpWebRequest;
                _request.Method = "POST";
                _request.ContentType = "application/x-www-form-urlencoded";
                _request.CookieContainer = new CookieContainer();
            }

            if (credentials != null)
            {
                _request.ContentLength = credentials.Length;
                using (var requestStream = _request.GetRequestStream())
                {
                    requestStream.Write(credentials, 0, credentials.Length);
                }
            }
            return _request.GetResponse() as HttpWebResponse;
        }
        #endregion
        #region 创建验证凭证
        /// <summary>
        /// 创建验证凭证
        /// <para>eg:</para>
        /// <para> IDictionary<string, string> _requestCredentials = new Dictionary<string, string>();</para>
        /// <para>_requestCredentials.Add("UserName", _userName);</para>
        /// <para>_requestCredentials.Add("PassWord", _userPwd);</para>
        /// <para>_requestCredentials.Add("MacAddress", _macAddress);</para>
        /// <para>byte[] _credentials = HttpWebRequestToolV2.CreateCredentials(_requestCredentials, Encoding.UTF8);</para>
        /// </summary>
        /// <returns>byte[]</returns>
        public static byte[] CreateCredentials(IDictionary<string, string> credentials, Encoding encoding)
        {
            StringBuilder _credentials = new StringBuilder();
            foreach (KeyValuePair<string, string> credential in credentials)
            {
                _credentials.AppendFormat("{0}={1}&", credential.Key, credential.Value);
            }
            string _credentialsString = _credentials.ToString().Trim();
            int _endIndex = _credentialsString.LastIndexOf('&');
            if (_endIndex != -1)
                _credentialsString = _credentialsString.Substring(0, _endIndex);
            return encoding.GetBytes(_credentialsString);
        }
        #endregion
        #region 获取网页HTML源码
        /// <summary>
        /// 获取网页HTML源码
        /// </summary>
        /// <param name="url">链接 eg:http://www.baidu.com/ </param>
        /// <param name="charset">编码 eg:Encoding.UTF8</param>
        /// <returns>HTML源码</returns>
        public static string GetHtmlSource(string url, Encoding charset)
        {

            string _html = string.Empty;
            try
            {
                HttpWebRequest _request = (HttpWebRequest)WebRequest.Create(url);
                HttpWebResponse _response = (HttpWebResponse)_request.GetResponse();
                using (Stream _stream = _response.GetResponseStream())
                {
                    using (StreamReader _reader = new StreamReader(_stream, charset))
                    {
                        _html = _reader.ReadToEnd();
                    }
                }
            }
            catch (WebException ex)
            {
                using (StreamReader sr = new StreamReader(ex.Response.GetResponseStream()))
                {
                    _html = sr.ReadToEnd();
                }
            }
            catch (Exception ex)
            {
                _html = ex.Message;
            }
            return _html;

        }
        #endregion
    }
}
